import { convertEnum, covertTableData } from '@/utils/tableUtil'
import { request } from '@umijs/max'

import { CustomerChannelVO, getCustomerChannelList } from '@/services/CustomerChannelService'
import {
  ModalForm,
  PageContainer,
  ProColumnType,
  ProFormDateTimePicker,
  ProFormMoney,
  ProFormSelect,
  ProFormText,
  ProTable,
} from '@ant-design/pro-components'
import { ActionType } from '@ant-design/pro-table/es/typing'
import { Button, message, Space } from 'antd'
import dayjs from 'dayjs'
import { ReactNode, useEffect, useRef, useState } from 'react'

/* ******************* 类型定义 ******************* */

/**
 * 客资渠道投放记录表实体类
 */
export interface DeliverLogVO {
  /**
   * 渠道id
   */
  channelId: string
  /**
   * 投放时间
   */
  deliverTime: string
  /**
   * 本次花费
   */
  fee: number
  /**
   * 编号
   */
  id?: string
}

/* ******************* 调用后端接口 ******************* */
/**
 * 获取客资投放记录分页数据
 * @param params
 */
const getDeliverLogPage = async (params?: any) => {
  // 请求接口
  let resp = await request<DeliverLogVO>(`/api/v2/deliverLog/deliverLogPage`, { params: params })
  // 将分页数据接口转换为ProTable格式的数据并返回
  return covertTableData(resp)
}

/**
 * 添加记录
 * @param dto
 */
const addDeliverLog = async (dto: DeliverLogVO) => {
  return request<DeliverLogVO>(`/api/v2/deliverLog/addDeliverLog`, { method: 'POST', data: dto })
}

/**
 * 修改记录
 * @param dto
 */
const editDeliverLog = async (dto: DeliverLogVO) => {
  return request<DeliverLogVO>(`/api/v2/deliverLog/editDeliverLog`, { method: 'POST', data: dto })
}

/**
 * 删除记录
 * @param idList
 */
const removeDeliverLog = async (idList: string[]) => {
  return request<DeliverLogVO>(`/api/v2/deliverLog/removeDeliverLog?idList=${idList}`, {
    method: 'POST',
  })
}

/* ******************* 页面Element ******************* */

// 页面
const DeliverLog = () => {
  const [channelList, setChannelList] = useState<CustomerChannelVO[]>([]) // 定义一个响应式State channelList=渠道列表 setChannelList=设置渠道列表
  const [currentDeliverLog, setCurrentDeliverLog] = useState<DeliverLogVO>() // 正在修改的对象
  const [isAdd, setIsAdd] = useState(false) // 当前是添加操作还是修改操作
  const [modalOpenState, setModalOpenState] = useState(false) // 当前模态框状态 true:打开 false:关闭
  const tableRef = useRef<ActionType>() // 定义表格的引用对象，可以可控的操作表格
  // 页面初始化时执行
  useEffect(() => {
    // 调用获取渠道列表接口
    getCustomerChannelList().then((res) => {
      // 把接口的返回值传入页面的State中
      setChannelList(res)
    })
  }, [])

  // 表格列定义
  const columns: ProColumnType<DeliverLogVO>[] = [
    {
      title: '渠道',
      dataIndex: 'channelId',
      valueEnum: convertEnum(channelList, { label: 'channelName', value: 'id' }), // 将渠道列表的数据转换成枚举的格式供ProTable自动映射
    },
    {
      title: '花费',
      hideInSearch: true,
      dataIndex: 'fee',
      renderText: (text) => `¥${text / 100}`, // 接口返回的fee字段单位是分, 转换成元后在表格中展示
    },
    {
      title: '投放时间',
      hideInSearch: true,
      dataIndex: 'deliverTime',
    },
    {
      title: '操作',
      render: (dom, record) => (
        <Space key="edit">
          <Button
            type="link"
            onClick={() => {
              // 1. 深拷贝一个对象，避免表单修改的时候改变表格的数据 record 代表当前行的数据
              let dto: DeliverLogVO = JSON.parse(JSON.stringify(record))
              // 2. 处理字段
              dto.fee = dto.fee / 100
              // 3. 设置表单默认值
              setCurrentDeliverLog(dto)
              // 4. 打开模态框
              setModalOpenState(true)
            }}
          >
            编辑
          </Button>
          <Button
            type="link"
            danger
            onClick={() => {
              if (record.id !== undefined) {
                removeDeliverLog([record.id])
                  .then(() => {
                    // 接口调用结束后刷新表格
                    message.success('删除成功').then()
                    tableRef.current?.reload()
                  })
                  .catch((e) => {
                    message.error('删除失败: ' + e).then()
                  })
              }
            }}
          >
            删除记录
          </Button>
        </Space>
      ),
    },
  ]

  // 表格操作栏
  const actions: ReactNode[] = [
    <Button
      key="add"
      type="primary"
      onClick={() => {
        // 1. 将操作类型改为添加
        setIsAdd(true)

        // 2. 获取渠道列表的第一个元素作为表单渠道字段的默认值
        let defaultChannelId: string = ''
        if (channelList.length > 0) {
          defaultChannelId = channelList[0].id
        }

        // 3. 初始化表单
        let initState: DeliverLogVO = {
          channelId: defaultChannelId, // 渠道id 默认渠道列表的第一个
          deliverTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), // 投放时间 默认当前时间
          fee: 0, // 投放金额
        }
        setCurrentDeliverLog(initState)

        // 4. 打开模态框
        setModalOpenState(true)
      }}
    >
      添加
    </Button>,
  ]

  /**
   * 处理表单提交
   * @param formData 表单数据
   */
  const handleSubmit = async (formData: DeliverLogVO) => {
    // 1. 深拷贝一个对象, 避免计算金额时修改模态框金额字段的值
    let dto: DeliverLogVO = JSON.parse(JSON.stringify(formData))
    // 2. 构造传给后端的JSON参数
    dto.fee = dto.fee * 100 // 输入的金额单位为元 转换为分后传给后端
    // 3. 判断调用添加还是修改接口
    try {
      if (isAdd) {
        // 当前为添加操作
        await addDeliverLog(dto)
      } else {
        // 修改操作
        await editDeliverLog(dto)
      }
    } catch (e) {
      // 如果接口报错, 执行下面逻辑
      message.error(`操作失败:${e}`)
      return false // 不关闭模态框
    }

    // 接口没有报错执行下面逻辑
    tableRef.current?.reload() // 刷新表格数据
    message.success('操作成功')
    return true // 如果请求接口没有报错, 关闭模态框
  }

  return (
    <PageContainer>
      {/* 表格部分 开始*/}
      <ProTable<DeliverLogVO>
        actionRef={tableRef}
        request={getDeliverLogPage}
        columns={columns}
        toolbar={{ actions: actions }}
      />
      {/* 表格部分 结束*/}

      {/*  模态框部分 开始*/}
      <ModalForm<DeliverLogVO>
        key={currentDeliverLog?.id || 0} // 当前操作对象的id作为模态框的key
        title={isAdd ? '添加记录' : '修改记录'}
        open={modalOpenState} // 通过传入的对象控制模态框是否打开 true | false
        onOpenChange={(state) => {
          setModalOpenState(state)
        }} // 模态框状态改变的回调函数  当模态框状态改变时, 设置modalOpenState的状态保持同步
        initialValues={currentDeliverLog} // 初始值
        modalProps={{
          destroyOnClose: true, // 当关闭后摧毁dom节点
        }}
        onFinish={handleSubmit}
      >
        <ProFormText label="编号" name="id" disabled hidden />
        <ProFormSelect
          label="渠道"
          name="channelId"
          valueEnum={convertEnum(channelList, { label: 'channelName', value: 'id' })}
        />
        <ProFormMoney
          label="投放金额"
          name="fee"
          rules={[
            { required: true, message: '投放金额不能为空' },
            { max: 50000, min: 1, message: '投放金额必须1～50000之间', type: 'integer' },
          ]}
        />
        <ProFormDateTimePicker label="投放时间" name="deliverTime" />
      </ModalForm>
      {/*  模态框部分 结束*/}
    </PageContainer>
  )
}

// 默认导出组件供路由使用
export default DeliverLog
